package com.pattern.behavioural;

/**
 * @author Ping
 * @date 2022/5/10 14:26
 **/
public class StateDemo {
    public static void main(String args[]) {
        Room room = new Room() ;
        room.book();
        room.book() ;
        room.checkin();
        room.checkout();
        room.book();
        room.cancle();


    }
}

/**
 * implemented in normal way
 */
//class Room {
//    public static final String BOOKED_STAT = "booked" ;
//    public static final String OCCUPIED_STAT = "occupied" ;
//    public static final String EMPTY_STAT = "empty" ;
//
//    private String state ;
//
//    public Room() {
//        this.state = EMPTY_STAT ;
//    }
//
//    public void book() {
//        if (this.state == EMPTY_STAT) {
//
//        } else if (this.state == BOOKED_STAT) {
//
//        } else {
//
//        }
//
//    }
//    public void checkin() {
//        if (this.state == EMPTY_STAT) {
//
//        } else if (this.state == BOOKED_STAT) {
//
//        } else {
//
//        }
//    }
//    public void checkout() {
//
//    }
//    public void cancle() {
//
//    }
//
//}
/**
 * by STATE PATTERN
 */
/**
 * Define a State, which should include related methods.
 */
abstract class RoomState {
    public abstract void book(Room room) ;
    public abstract void checkin(Room room) ;
    public abstract  void checkout(Room room) ;
    public abstract void cancle(Room room) ;
}

/**
 * From state to  method implementation.
 */
class EmptyState extends RoomState {
    @Override
    public void book(Room room) {
        System.out.println("the room was booked.") ;
        /**
         * NOTE that, the state could/should be shared.
         */
        room.setState(new BookedState());
    }

    @Override
    public void checkin(Room room) {
        System.out.println("the room was checked in.") ;
        room.setState(new OccupiedState());
    }

    @Override
    public void checkout(Room room) {
        System.out.println("the room could not be check out.") ;
    }

    @Override
    public void cancle(Room room) {
        System.out.println("the room could not be cancled.") ;
    }
}

class BookedState extends RoomState {
    @Override
    public void book(Room room) {
        System.out.println("the room could not be booked, since it was already booked") ;
    }

    @Override
    public void checkin(Room room) {
        System.out.println("the room was checked in.") ;
        room.setState(new OccupiedState());
    }

    @Override
    public void checkout(Room room) {
        System.out.println("the room could not be checked out.") ;
    }

    @Override
    public void cancle(Room room) {
        System.out.println("the room was cancled.") ;
        room.setState(new EmptyState());
    }
}
class OccupiedState extends RoomState {
    @Override
    public void book(Room room) {
        System.out.println("the room could not be booked.") ;
    }

    @Override
    public void checkin(Room room) {
        System.out.println("the room could not be checked in.") ;
    }

    @Override
    public void checkout(Room room) {
        System.out.println("the room was checked out") ;
        room.setState(new EmptyState());
    }

    @Override
    public void cancle(Room room) {
        System.out.println("the room could not be cancled.") ;
    }
}

class Room {
    private RoomState state ;

    public Room() {
        this.state = new EmptyState() ;
    }
    public void setState(RoomState state) {
        this.state = state ;
    }
    public void book() {
        this.state.book(this);
    }
    public void checkin() {
        this.state.checkin(this);
    }
    public void checkout() {
        this.state.checkout(this);
    }
    public void cancle() {
        this.state.cancle(this);
    }
}


